home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_100
/
130_01
/
ry.c
< prev
next >
Wrap
Text File
|
1985-03-09
|
24KB
|
899 lines
/********************************************************************
ry.c - library of file handlers
*/
/* changes */
/*
following applies to rx package, father of ry:
7/25/81- put this file on seperate development disk, ALL
development to this package to be done here only. crl files
may be spread around as needed.
7/7/81- made ropen() free allocated buffer space before
returning on ERROR. Don't close files that return ERROR
from ropen().
7/7/81- made rclose do primitive close even if buffer not
flushed correctly, insuring that fd is always freed.
8/18/81- corrected to be grammatically identical to unix
call syntax (almost, still additional arg to ropen and rcreat
to explicitly set file buffer size).
2/14/82- add stderr, virtual console, virtual modem, and
vcon & vmodem to rgetc() and rputc().
3/16/82- remove virtual stuff.
5/30/82 - remove 'byte' and 'string' defines from code
5/30/82 - change all 'FILE' to 'RFILE' for ver 1.46
6/7/82 - fix ropen() setting of fp->_bufbase to '= fp + 1'
7/14/82 - fix rclose to free memory AFTER using fd to free file
9/9/82 - add bs (binary search file) code to package. got it from
bs.c, not fron cnlib, will save cnlib for a while...
no, maybe I did get it from cnlib....
end of comments/changes on rx stuff
*/
/*
following applies to ry package:
9/11/82 - change over to ry disk, rename rx files to ry for starters, etc.
change fseek() and ftell() to work with 'long' int
rename them to lseek() and ltell(), respectively.
*/
#include "a:std.h" /* bdscio.h + my stuff */
#include <ry.h> /* stuff for this package */
/*
purge any old copies, creat and open 'filename', buffer
size equal to secs * size of one sector, mode of write (from
beginning of file), append (write at end of file), or direct
(read or write, starting at beginning of file, random access
to any part of file). read not allowed as you can't read a
new file.
*/
RFILE * /* returns pointer to RFILE struct, or ERROR on error */
rcreat(filename, mode, secs)
char *filename;
char mode;
int secs;
{
int fd;
char dummy_h[SECSIZ];
RFILE *ropen();
setmem(dummy_h, SECSIZ, 0); /* nulls */
switch (mode) {
case 'r': return ERROR; /* can't read empty file */
case 'w':
case 'a':
case 'd':
if ((fd = creat(filename)) == ERROR ) return ERROR;
if (write(fd, dummy_h, 1) != 1) {
fabort(fd);
return ERROR; /* dummy header */
}
if (close(fd) == ERROR) return ERROR; /* free up fd */
return ropen(filename, mode, secs); /* open */
default:
return ERROR;
}
}
/*
open 'filename' buffer in space provided by alloc(), setup
fp, buffer of size SECSIZ * secs
*/
RFILE * /* returns pointer to RFILE or ERROR on error */
ropen(filename, mode, secs)
char *filename;
char mode;
int secs;
{
RFILE *fp;
int fd;
char *alloc();
unsigned rcfsiz(), rsrec();
switch (mode) {
case 'r': /* read mode */
/* fd = open(filename, 0); /* open read */
break;
*/
case 'w': /* write mode */
/* case 'a': /* append mode */ not supported yet */
case 'd': /* direct or random */
fd = open(filename, 2); /* open r/w */
break;
default: return ERROR;
}
if (fd == ERROR) return ERROR; /* open error */
if ((fp = alloc(((secs + 1) * SECSIZ) + sizeof(*fp))) == 0) return ERROR;
/* no room for buffer */
fp -> _rfd = fd; /* file descriptor */
fp -> _bufbase = fp + 1; /* start of file buffer */
fp -> _bufbase += SECSIZ; /* room for header */
fp -> _secs = secs; /* secs. in buffer */
fp -> _nxtbyt = fp -> _bufbase; /* start at begin of buf */
fp -> _pastbuf = fp -> _bufbase + (secs * SECSIZ); /* endbuf */
fp -> _mode = mode;
/** 'a' not supported yet...
fp -> _frstsec = (mode == 'a') ? /* if 'a' start at end */
rcfsiz(fp->_rfd) : rsrec(fp->_rfd); /* else at 0 */
**/
if (read(fd, fp + 1, 1) < 0) { /* get file header into core */
free(fp);
return ERROR;
}
fp -> _frstsec = rsrec(fp->_rfd); /* start at sector 1 */
if (_fillbuf(fp) == ERROR ) { /* fill the buffer */
free(fp);
return ERROR;
}
return fp;
}
/*
flushes, then closes the random file at fp
*/
rclose(fp) /* return -1 on error */
RFILE *fp;
{
int err_flag;
err_flag = _rflush(fp); /* flush buffer */
if (seek(fp->_rfd, 0, 0) == ERROR) err_flag = ERROR; /* get to sec 0 */
if (write(fp->_rfd, fp+1, 1) != 1) err_flag = ERROR; /* update header */
if (close(fp->_rfd) == ERROR) err_flag = ERROR; /* close it */
free(fp); /* free buffer space */
return err_flag; /* did it flush ok? */
}
/*
fills buffer pointed at by fp->_bufbase, with file fp->_rfd,
with fp->_secs sectors, starting with cp/m random record field
lseek calls this after updating cp/m's rrf and fp's pointers (if
necessary because seek is out of buffer area)
*/
_fillbuf(fp) /* return -1 on error, 0 if OK */
RFILE *fp;
{
int fd, secs, got;
char *base;
unsigned rseek();
fd = fp -> _rfd;
secs = fp -> _secs;
base = fp -> _bufbase;
/* call rread for sectors till buffer full or ERROR */
/* try to read all of buffer */
while (secs -= (got = rread(fd, base, secs))) {
if ((got > 1000) OR (got == -1)) return ERROR;
/* unwritten random sector in buffer area */
setmem((base += (got * SECSIZ)), SECSIZ, 0);
/* fill this sector with 0's */
base += SECSIZ; /* inc. buffer ptr */
rseek(fd, 1, 1); /* inc. file ptr */
--secs; /* this one filled with 0 */
} /* try filling rest of buffer */
fp -> _update = NO; /* clear update flag */
return OK;
}
/*
flushes the buffer fp->_bufbase if open for writing AND
fp->_update shows the buffer has indeed been written to since
last _fillbuf call. ignores flushes of i/o devices
*/
_rflush(fp) /* return -1 on error, 0 if OK */
RFILE *fp;
{
unsigned rseek();
if ((fp < 4) OR (fp->_mode == 'r') OR (fp->_update == NO))
return OK; /* don't bother */
if (rseek(fp -> _rfd,fp -> _frstsec, 0) == ERROR) return ERROR;
/* seek first bufferd sec and ... */
if (rwrite(fp->_rfd, fp->_bufbase, fp->_secs) != fp->_secs)
return ERROR; /* ...write entire buffer to disk */
fp -> _update = NO; /* clear update flag */
return OK;
}
/*
sets '_nxtbyt' of 'fp' to 'offset' (a long int) from
'origin' , returns offset.
*/
unsigned /* returns (long int) offset, -1 on error */
lseek(fp, offset, origin)
RFILE *fp;
char *offset;
int origin;
{
unsigned sector, byt;
char longint[4], os[4], os2[4], lsecsiz[4];
unsigned rseek(), rcfsiz();
char *ltell();
itol(lsecsiz, SECSIZ); /* set logical sector size */
if (origin == 0) { /* from beginning of file */
movmem(offset, os, 4); /* make local copy */
}
else if (origin == 1) {
ladd(os, offset, ltell(fp, longint)); /* pres pos + offset to os */
}
else if (origin == 3) { /* ascii offset from start */
atol(os, offset);
}
else if (origin == 4) { /* ascii from pres pos */
atol(os2, offset);
ladd(os, os2, ltell(fp, longint)); /* pres pos + offset to os */
}
else return ERROR; /* only legal orgs now */
if (os[3] | os[2]) return ERROR; /* within legal range? */
ltou(§or, ldiv(longint, os, lsecsiz)); /* byte / secsiz = sectors */
ltou(&byt, lmod(longint, os, lsecsiz)); /* remainder = bytes */
++sector; /* reserve sec 0 for future */
if ((sector >= fp->_frstsec) AND /* if in buffer */
(sector < (fp->_frstsec + fp->_secs))) {
fp->_nxtbyt = (sector - fp->_frstsec)*SECSIZ
+ byt + fp->_bufbase; /* point to it */
return offset; /* and return */
}
if (_rflush(fp) == ERROR) return ERROR; /* else flush buf */
if (rseek(fp->_rfd, sector, 0) == ERROR) return ERROR;
fp->_frstsec = sector; /* seek sec in file, */
fp->_nxtbyt = byt + fp->_bufbase; /* and init ptrs */
if (_fillbuf(fp) == ERROR) return ERROR; /* fill buf */
return offset;